package org.ziyao.generatezippdf.controller;

import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.Property;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import org.ziyao.generatezippdf.entity.DeptBean;
import org.ziyao.generatezippdf.entity.OriginBean;
import org.ziyao.generatezippdf.entity.SixBean;
import reactor.core.publisher.Mono;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
@RequiredArgsConstructor
@RequestMapping("report")
public class AiReportController {

    private static final String REMOTE_FONT_URL = "http://dsd.nmgbigdata.com:1002/static/FangZhengFangSong.ttf";
    private static final String REMOTE_FONT_URL_HEITI = "http://dsd.nmgbigdata.com:1002/static/FangZhengHeiTi.ttf";
    private static final String REMOTE_FONT_URL_XIAOBIAOSONG = "http://dsd.nmgbigdata.com:1002/static/FangZhengXiaoBiaoSong.ttf";
    private static final String REMOTE_FONT_URL_FONGSONGNUMBER = "http://dsd.nmgbigdata.com:1002/static/FangSongNumber.ttf";
//    private static final String TEMP_FONT_PATH = "./temp_font.ttf"; // 临时字体文件路径
    private static final String TEMP_FONT_PATH = "fonts/temp_font.ttf"; // 临时字体文件路径
    private static final String TEMP_FONT_PATH_HEITI = "fonts/temp_font_heiti.ttf"; // 临时字体文件路径
    private static final String TEMP_FONT_PATH_XIAOBIAOSONG = "fonts/temp_font_xiaobiaosong.ttf"; // 临时字体文件路径
    private static final String TEMP_FONT_PATH_FONGSONGNUMBER = "fonts/temp_font_fangsongnumber.ttf"; // 临时字体文件路径

    private static final String PDF_DIRECTORY = ".\\generateZipPdf\\"; // PDF文件所在的目录


    @GetMapping("create2")
    private ResponseEntity<ByteArrayResource> generatePdf() throws IOException {

//        downloadFontFile(REMOTE_FONT_URL, TEMP_FONT_PATH);
//        downloadFontFile(REMOTE_FONT_URL_HEITI, TEMP_FONT_PATH_HEITI);
//        downloadFontFile(REMOTE_FONT_URL_XIAOBIAOSONG, TEMP_FONT_PATH_XIAOBIAOSONG);
//        downloadFontFile(REMOTE_FONT_URL_FONGSONGNUMBER, TEMP_FONT_PATH_FONGSONGNUMBER);

        WebClient client = WebClient.builder()
                .baseUrl("http://dsd.nmgbigdata.com:1002")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
        Mono<OriginBean> mono = client
                .get()  // GET请求
                .uri("/dsd/magic/api/biz/contact_sys/evaluation/evaluation_march/top")   // 请求路径
                .retrieve()   // 获取响应体
                .bodyToMono(OriginBean.class);

        OriginBean originBean = mono.block();
        List<DeptBean> deptBeans = originBean.getData();

        WebClient clientQxq = WebClient.builder()
                .baseUrl("http://dsd.nmgbigdata.com:1002")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
        Mono<OriginBean> monoQxq = clientQxq
                .get()  // GET请求
                .uri("/dsd/magic/api/biz/contact_sys/evaluation/evaluation_march/top_qxq")   // 请求路径
                .retrieve()   // 获取响应体
                .bodyToMono(OriginBean.class);

        OriginBean originBeanQxq = monoQxq.block();
        deptBeans.addAll(originBeanQxq.getData());

        // 遍历数据集，为每个条目生成PDF
        for (DeptBean deptItem : deptBeans) {
            setTemplate(deptItem);
        }

        // 获取PDF目录下的所有PDF文件
        Path pdfDirectory = Paths.get(PDF_DIRECTORY);
        List<Path> pdfFiles = Files.list(pdfDirectory)
                .filter(path -> path.toString().endsWith(".pdf"))
                .collect(Collectors.toList());

        // 创建ZIP输出流和字节数组输出流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
        // 遍历PDF文件，将它们添加到ZIP压缩包中
        for (Path pdfFile : pdfFiles) {
            String fileName = pdfFile.getFileName().toString();
            FileInputStream fileInputStream = new FileInputStream(pdfFile.toFile());
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOutputStream.putNextEntry(zipEntry);

            byte[] buffer = new byte[1024];
            int len;
            while ((len = fileInputStream.read(buffer)) > 0) {
                zipOutputStream.write(buffer, 0, len);
            }

            fileInputStream.close();
            zipOutputStream.closeEntry();
        }
        // 关闭ZIP输出流
        zipOutputStream.close();

        // 获取ZIP压缩包的字节数组
        byte[] zipBytes = byteArrayOutputStream.toByteArray();
        // 设置HTTP响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "pdfs.zip"); // 设置下载文件名
        // 创建并返回响应实体
        ByteArrayResource resource = new ByteArrayResource(zipBytes);

        return new ResponseEntity<>(resource, headers, HttpStatus.OK);
//        return GraceJSONResult.ok("报告已生成完毕！存放到D:/generateZipPdf文件夹");

    }


    // pdf模板设置
    private void setTemplate(DeptBean deptItem) {
        // 输出文件路径
        // 生成PDF文件名
        String pdfFileName = PDF_DIRECTORY + deptItem.getId() + "_" + deptItem.getName()+ ".pdf";
        // 创建文件夹
        Path pdfPath = Paths.get(pdfFileName).getParent();
        if (pdfPath != null && !Files.exists(pdfPath)) {
            try {
                Files.createDirectories(pdfPath);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("创建文件夹时出错：" + e.getMessage());
            }
        }

        try {
            // 创建一个PdfWriter实例
            PdfWriter pdfWriter = new PdfWriter(new FileOutputStream(pdfFileName));

            PdfDocument pdf = new PdfDocument(pdfWriter);
            Document document = new Document(pdf, PageSize.A4);
            // 创建PdfDocument和Document实例，并设置页边距
            // 参数依次为：左边距、上边距、右边距、下边距（单位：点 * 28.35 = 厘米）
            float marginTop = 3.7f * 28.346f;  // 上边距
            float marginRight = 2.6f * 28.346f; // 右边距
            float marginBottom = 3.5f * 28.346f ; // 下边距
            float marginLeft = 2.8f * 28.346f; // 左边距
            document.setMargins(marginTop, marginRight, marginBottom, marginLeft);

            // 加载临时字体文件
            PdfFont font = PdfFontFactory.createFont(TEMP_FONT_PATH, PdfEncodings.IDENTITY_H);
            PdfFont font_hei = PdfFontFactory.createFont(TEMP_FONT_PATH_HEITI, PdfEncodings.IDENTITY_H);
            PdfFont font_biaosong = PdfFontFactory.createFont(TEMP_FONT_PATH_XIAOBIAOSONG, PdfEncodings.IDENTITY_H);
            PdfFont fontsong_number = PdfFontFactory.createFont(TEMP_FONT_PATH_FONGSONGNUMBER, PdfEncodings.IDENTITY_H);

            // 设置大标题
            Paragraph paragraph = new Paragraph(deptItem.getName() + "数字化及用数评估结果")
                    .setFont(font_biaosong)
                    .setFontSize(22)   // 二号字 22 三号字16pt
                    .setMarginBottom(22)
                    .setTextAlignment(TextAlignment.CENTER);

            // 将Paragraph添加到文档中
            document.add(paragraph);

            // 分页标题
            Paragraph paragraph2_1 = new Paragraph("【评估情况】")
                    .setFont(font_hei)
                    .setFontSize(18)   // 二号字 22 小二号 18 三号字16pt
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(paragraph2_1);
            // 总分
            Paragraph paragraph3 = new Paragraph("得分：" + deptItem.getTotal() + "分")
                    .setFont(fontsong_number)
                    .setFontSize(16)   // 二号字 22 小二号 18 三号字16pt
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(paragraph3);

            // 雷达图
            String filePath = "file:///D:/Downloads/" + deptItem.getId() + "_" + deptItem.getName() + ".png";
            File file = new File(filePath);

            if (!file.exists() || file.isFile()) {
                ImageData imageData = ImageDataFactory.create(filePath);
                Image image = new Image(imageData);
                // 将图片缩放到宽度为28.35点 * 12.83厘米 = ?pt，高度按比例缩放
                float scaledWidth = 12.83f * 28.35f;
                image.scaleToFit(scaledWidth, image.getImageScaledHeight());
                image.setProperty(Property.HORIZONTAL_ALIGNMENT, HorizontalAlignment.CENTER);
                document.add(image);
            }
            // 表格
            Table table = new Table(7);
            table.setMarginTop(30);
            // 单元格高度
//            Float[] tdHeight = {0.97f*28.35f, 1.36f*28.35f, 1.36f*28.35f, 1.36f*28.35f };
            Float[] tdHeight = {0.97f*28.35f, 1.16f*28.35f, 1.16f*28.35f, 1.16f*28.35f };
            // 填充表格内容  // 一级指标	数字化情况	数据共享	数据应用	数据分析	AI+	数据安全
            String[] tableHeader = {"一级指标", "数字化情况", "数据共享", "数据应用", "数据分析", "AI+", "数据安全"};
            for (int i = 0; i < 7; i++) { // 7列
                Cell cell = new Cell();
                Paragraph p = new Paragraph(tableHeader[i])
                        .setFont(font_hei)
                        .setFontSize(12)   // 二号字 22 小二号 18 三号字16pt
                        .setFixedLeading(26)
                        .setTextAlignment(TextAlignment.CENTER);
                cell.add(p);
                cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
                cell.setPaddingLeft(8);
                cell.setPaddingRight(8);
                cell.setHeight(tdHeight[0]);
                table.addCell(cell);
            }

            // 第2行 自己得分情况
            Cell cell2 = new Cell();
            cell2.setHeight(tdHeight[1]);
            cell2.setVerticalAlignment(VerticalAlignment.MIDDLE);
            Paragraph p2 = new Paragraph("得分情况")
                    .setFont(font_hei)
                    .setFontSize(12)   // 二号字 22 小二号 18 三号字16pt
                    .setFixedLeading(26)
                    .setTextAlignment(TextAlignment.CENTER);
            cell2.add(p2);
            table.addCell(cell2);

            SixBean selfScore = deptItem.getReport().get(2).getValue();
            for (Field f: SixBean.class.getDeclaredFields()) {
                f.setAccessible(true); // 设置字段为可访问，如果它是私有的
                Cell cell = new Cell();
                cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
                Paragraph p = new Paragraph(String.valueOf(f.get(selfScore)))
                        .setFont(fontsong_number)
                        .setFontSize(12)   // 二号字 22 小二号 18 三号字16pt
                        .setTextAlignment(TextAlignment.CENTER);
                p.setTextAlignment(TextAlignment.CENTER); // 设置文本居中
                cell.add(p);
                table.addCell(cell);
            }

            // 第3行 平均分
            Cell cell3 = new Cell();
            cell3.setHeight(tdHeight[2]);
            cell3.setVerticalAlignment(VerticalAlignment.MIDDLE);
            Paragraph p3 = new Paragraph("平均分")
                    .setFont(font_hei)
                    .setFontSize(12)   // 二号字 22 小二号 18 三号字16pt
                    .setTextAlignment(TextAlignment.CENTER);
            cell3.add(p3);
            table.addCell(cell3);

            SixBean averScore = deptItem.getReport().get(1).getValue();
            for (Field f: SixBean.class.getDeclaredFields()) {
                f.setAccessible(true); // 设置字段为可访问，如果它是私有的
                Cell cell = new Cell();
                cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
                Paragraph p = new Paragraph(String.valueOf(f.get(averScore)))
                        .setFont(fontsong_number)
                        .setFontSize(12)   // 二号字 22 小二号 18 三号字16pt
                        .setTextAlignment(TextAlignment.CENTER);
                cell.add(p);
                table.addCell(cell);
            }

            // 第4行 最高分
            Cell cell4 = new Cell();
            cell4.setHeight(tdHeight[3]);
            cell4.setVerticalAlignment(VerticalAlignment.MIDDLE);
            Paragraph p4 = new Paragraph("最高分")
                    .setFont(font_hei)
                    .setFontSize(12)   // 二号字 22 小二号 18 三号字16pt
                    .setTextAlignment(TextAlignment.CENTER);
            cell4.add(p4);
            table.addCell(cell4);

            SixBean maxScore = deptItem.getReport().get(0).getValue();
            for (Field f: SixBean.class.getDeclaredFields()) {
                f.setAccessible(true); // 设置字段为可访问，如果它是私有的
                Cell cell = new Cell();
                cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
                Paragraph p = new Paragraph(String.valueOf(f.get(maxScore)))
                        .setFont(fontsong_number)
                        .setFontSize(12)   // 二号字 22 小二号 18 三号字16pt
                        .setTextAlignment(TextAlignment.CENTER);
                cell.add(p);
                table.addCell(cell);
            }

            document.add(table);

            AreaBreak areaBreak = new AreaBreak();
            document.add(areaBreak); // 在此处强制分页
            // 分页标题
            Paragraph paragraph2_2 = new Paragraph("【部门自评】")
                    .setFont(font_hei)
                    .setFontSize(18)   // 二号字 22 小二号 18 三号字16pt
                    .setFixedLeading(26)
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(paragraph2_2);

           // 自评 数字化情况
            createWord(document, "一、数字化情况：", deptItem.getZpSzhqk(), font_hei, font);

            // 自评 二、数据共享及数据分析工作开展情况
            createWord(document, "二、数据共享及数据分析工作开展情况：", deptItem.getZpSjgx(), font_hei, font);

            // 自评 三、存在的问题
            createWord(document, "三、存在的问题：", deptItem.getZpCzwt(), font_hei, font);

            // 自评 四、下一步工作思路
            createWord(document, "四、下一步工作思路：", deptItem.getXybgzsl(), font_hei, font);


            document.close();

            System.out.println("PDF created successfully: " + pdfFileName);
        } catch (Exception e) {

            e.printStackTrace();
        }

    }

    // 从远程URL下载文件到本地路径的方法
    private void downloadFontFile(String remoteUrl, String localPath) throws IOException {
        URL url = new URL(remoteUrl);
        URLConnection connection = url.openConnection();
        try (InputStream inputStream = new BufferedInputStream(connection.getInputStream());
             FileOutputStream outputStream = new FileOutputStream(localPath)) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }
    }

    // 生成自评
    private void createWord(Document document, String title, String content, PdfFont font_title, PdfFont font_content) {
        Text text = new Text(title);
        text.setFont(font_title);

        if (content == null) {
            content = "-";
        }
        Text text1 = new Text(content);
        text1.setFont(font_content);

        Paragraph paragraph = new Paragraph();
        paragraph.add(text);
        paragraph.add(text1);
        paragraph.setFontSize(16);   // 二号字 22 小二号 18 三号字16pt
        paragraph.setFixedLeading(26);
        paragraph.setFirstLineIndent(2 * 16f);
        paragraph.setVerticalAlignment(VerticalAlignment.TOP);
        paragraph.setSpacingRatio(1);
        document.add(paragraph);
    }


}
